﻿
Option Explicit On
'*******************************************************************
' Program: pkgVisio
' Author: Albert E Edlund
' Date:
'
' Purpose:
' Working with office object XML
'
'*******************************************************************

#Region " imports "

Imports System
Imports System.Object
Imports System.IO
Imports System.IO.TextReader
' need to reference windowsbase in .net
Imports System.IO.Packaging

' need for dbconnectionstringbuilder used in clsConnections
Imports System.Data.Common

Imports System.Windows
Imports System.Windows.Forms
Imports System.Text.StringBuilder

Imports Microsoft.VisualBasic

Imports System.Text
Imports System.Collections
Imports System.Collections.Generic
Imports System.Collections.ObjectModel

Imports System.Xml
Imports System.Linq
Imports System.Linq.Enumerable
Imports System.Windows.Input

Imports System.Xml.Serialization
Imports System.Xml.Linq
Imports System.Xml.XPath

Imports ADODB
Imports System.Data
Imports System.Data.OleDb
Imports System.Data.Sql


Imports Microsoft.Practices.EnterpriseLibrary.Common
Imports Microsoft.Practices.EnterpriseLibrary.ExceptionHandling
Imports Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging


' visio v15 does not use a xName prefix which may put it into conflict with other open office apps
Imports <xmlns="http://schemas.microsoft.com/office/visio/2012/main">
Imports <xmlns:rs="urn:schemas-microsoft-com:rowset">

' generic namespace for office open xml, used in all of them
Imports <xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">

Imports pkgVisio.clsVisPackage
Imports pkgVisio.clsStructures


#End Region


'**********************************************************************************
'
'**********************************************************************************
'
Public Class clsValidation

#Region " Properties and Declarations"




    '
    '
    '
    Public m_xDoc As XDocument
    Public Property xDoc As XDocument
        Get
            Return Me.m_xDoc
        End Get
        Set(value As XDocument)
            If (value Is Nothing) Then
                Throw New System.ArgumentNullException("Value", _
                    "xDoc is Null.")
            End If
            Me.m_xDoc = value
        End Set
    End Property



    ' the local class definitions
    Public m_visPackage As clsVisPackage
    Public Property visPackage As clsVisPackage
        Get
            visPackage = Me.m_visPackage
        End Get
        Set(value As clsVisPackage)
            If (value Is Nothing) Then
                Throw New System.ArgumentNullException("Value", _
                    "visPackage is Null.")
            End If
            Me.m_visPackage = value
        End Set
    End Property


#End Region

#Region " validation ruleset "

    Public Structure valRuleSet
        Public rulesetId As Long
        Public rulesetNameU As String
        Public rulesetDescr As String

        Public Sub New _
            (lngId As Long, _
             strNameU As String, _
             strDescr As String)

            rulesetId = lngId
            rulesetNameU = strNameU
            rulesetDescr = strDescr

        End Sub
    End Structure

    '
    '
    '
    Private _dictRuleSets As Dictionary(Of Long, valRuleSet)
    Public Property dictRuleSets As Dictionary(Of Long, valRuleSet)
        Get
            dictRuleSets = Me._dictRuleSets
        End Get
        Set(value As Dictionary(Of Long, valRuleSet))
            Me._dictRuleSets = value
        End Set
    End Property


    '
    ' load a list of ruleset names and ids into a list control
    '
    Public Sub getRuleSets()

        Try

            Me._dictRuleSets = Nothing
            Me.dictRuleSets = New Dictionary(Of Long, valRuleSet)
            Me._dictRules = Nothing
            Me.dictRules = New Dictionary(Of valRuleId, valRule)


            Dim qryRuleSet = Me.xDoc...<RuleSet>
            Dim intRuleSet As Integer = qryRuleSet.Count

            For Each ruleset In qryRuleSet

                Dim lngRuleSetId As Long = -1
                Dim strRuleSetNameU As String = "NoRuleSetNameU"
                Dim strRuleSetName As String = "NoRuleSetName"
                Dim strRuleSetDescription As String = "NoRuleSetDescription"


                Dim listOfAttributes As IEnumerable(Of XAttribute) = _
                    From att In ruleset.Attributes() _
                    Select att
                For Each att As XAttribute In listOfAttributes
                    ' Console.WriteLine("{0}={1}", att.Name.LocalName, att.Value)
                    Select Case LCase(att.Name.LocalName)
                        Case "id"
                            lngRuleSetId = CLng(att.Value)
                        Case "nameu"
                            strRuleSetNameU = CStr(att.Value)
                        Case "description"
                            strRuleSetDescription = CStr(att.Value)
                    End Select
                Next att

                Dim blnFound As Boolean = False
                Try
                    blnFound = dictRuleSets.ContainsKey(lngRuleSetId)
                Catch err As System.Collections.Generic.KeyNotFoundException
                End Try
                If blnFound = False Then
                    Dim newRuleSet As valRuleSet = New valRuleSet _
                                                   (lngRuleSetId, _
                                                    strRuleSetNameU, _
                                                    strRuleSetDescription)
                    dictRuleSets.Add(lngRuleSetId, newRuleSet)
                End If

                ' do the init stuff for the first record
                If dictRuleSets.Count = 1 Then
                    getRules(ruleset)
                End If


            Next ruleset

        Catch errXml As XmlException
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(errXml, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        End Try

    End Sub

    '
    '
    '
    Public Sub loadRuleSetLvControl(ByRef lvControl As ListView)

        Try


            If lvControl IsNot Nothing Then
                lvControl.Items.Clear()
                lvControl.Columns.Clear()
                lvControl.View = View.Details
                lvControl.AllowColumnReorder = True
                lvControl.FullRowSelect = True
                lvControl.Columns.Add("Id", 50, HorizontalAlignment.Right)
                lvControl.Columns.Add("NameU", 100, HorizontalAlignment.Left)
                lvControl.Columns.Add("Descr", 100, HorizontalAlignment.Left)

                Dim lvItem As ListViewItem


                For Each rulesetFound In dictRuleSets

                    lvItem = New ListViewItem(rulesetFound.Value.rulesetId.ToString)
                    lvItem.SubItems.Add(rulesetFound.Value.rulesetNameU.ToString)
                    lvItem.SubItems.Add(rulesetFound.Value.rulesetDescr.ToString)

                    ' add it to the listview on the data page
                    lvControl.Items.Add(lvItem)

                Next rulesetFound

                If lvControl.Items.Count > 0 Then
                    lvControl.Focus()
                    lvControl.Items(0).Selected = True
                End If

            End If

        Catch errXml As XmlException
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(errXml, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        End Try

    End Sub

#End Region

#Region " validation rule "

    Public Structure valRuleId
        Public rulesetId As Long
        Public ruleId As Long

        Public Sub New _
            (lngSet As Long, _
             lngRule As Long)

            rulesetId = lngSet
            ruleId = lngRule

        End Sub

    End Structure

    Public Structure valRule
        Public ruleId As Long
        Public ruleNameU As String
        Public ruleCategory As String
        Public ruleDescr As String
        Public ruleFilter As String
        Public ruleTest As String

        Public Sub New _
            (lngId As Long, _
            strNameU As String, _
            strCat As String, _
            strDescr As String, _
            strFilter As String, _
            strTest As String)

            ruleId = lngId
            ruleNameU = strNameU
            ruleCategory = strCat
            ruleDescr = strDescr
            ruleFilter = strFilter
            ruleTest = strTest
        End Sub

    End Structure

    Private _dictRules As Dictionary(Of valRuleId, valRule)
    Public Property dictRules As Dictionary(Of valRuleId, valRule)
        Get
            dictRules = Me._dictRules
        End Get
        Set(value As Dictionary(Of valRuleId, valRule))
            Me._dictRules = value
        End Set
    End Property


    '
    ' load a list of rule names and ids into a dictionary
    '
    Public Sub getRules _
        (ByVal ruleSource As XElement)

        If Me._dictRules IsNot Nothing Then
            Me._dictRules = Nothing
        End If
        Me.dictRules = New Dictionary(Of valRuleId, valRule)

        Try


            Dim qryRules = ruleSource...<Rule>
            Dim intRules As Integer = qryRules.Count

            For Each rules In qryRules

                Dim lngRuleParent As Long = CLng(rules.Parent.@ID)

                Dim lngRuleId As Long = -1
                Dim strRuleNameU As String = "NoRuleNameU"
                Dim strRuleCategory As String = "NoRuleCategory"
                Dim strRuleName As String = "NoRuletName"
                Dim strRuleDescription As String = "NoRuleDescription"
                Dim strRuleFilter As String = "NoRuleFilter"
                Dim strRuleTest As String = "NoRuleTest"

                ' first go through the attributes for the rule

                Dim listOfAttributes As IEnumerable(Of XAttribute) = _
                    From att In rules.Attributes() _
                    Select att
                For Each att As XAttribute In listOfAttributes
                    ' Console.WriteLine("{0}={1}", att.Name.LocalName, att.Value)
                    Select Case LCase(att.Name.LocalName)
                        Case "id"
                            lngRuleId = CLng(att.Value)
                        Case "nameu"
                            strRuleNameU = CStr(att.Value)
                        Case "description"
                            strRuleDescription = CStr(att.Value)
                        Case "category"
                            strRuleCategory = CStr(att.Value)
                        Case "rulefilter"
                            strRuleFilter = CStr(att.Value)
                        Case "ruletest"
                            strRuleTest = CStr(att.Value)
                    End Select
                Next att

                Dim newId As valRuleId = New valRuleId(lngRuleParent, lngRuleId)
                Dim blnFound As Boolean = False
                Try
                    blnFound = dictRules.ContainsKey(newId)
                Catch err As System.Collections.Generic.KeyNotFoundException
                End Try
                If blnFound = False Then
                    Dim newRule As valRule = New valRule _
                                             (lngRuleId, _
                                              strRuleNameU, _
                                              strRuleCategory, _
                                              strRuleDescription, _
                                              strRuleFilter, _
                                              strRuleTest)
                    dictRules.Add(newId, newRule)
                End If
            Next rules

        Catch errXml As XmlException
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(errXml, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        End Try

    End Sub

    '
    '
    '
    Public Sub loadRulesLvControl _
        (ByRef lvControl As ListView)


        Try


            If lvControl IsNot Nothing Then

                Dim lvItem As ListViewItem

                lvControl.Items.Clear()
                lvControl.Columns.Clear()
                lvControl.View = View.Details
                lvControl.AllowColumnReorder = True
                lvControl.FullRowSelect = True
                lvControl.Columns.Add("Id", 50, HorizontalAlignment.Right)
                lvControl.Columns.Add("NameU", 200, HorizontalAlignment.Left)
                'lvControl.Columns.Add("Category", 100, HorizontalAlignment.Left)
                'lvControl.Columns.Add("Descr", 100, HorizontalAlignment.Left)
                'lvControl.Columns.Add("Filter", 100, HorizontalAlignment.Left)
                'lvControl.Columns.Add("Test", 100, HorizontalAlignment.Left)

                For Each ruleFound In dictRules

                    ' build the listview control
                    lvItem = New ListViewItem(ruleFound.Value.ruleId.ToString)
                    lvItem.SubItems.Add(ruleFound.Value.ruleNameU.ToString)
                    'lvItem.SubItems.Add(strRuleCategory)
                    'lvItem.SubItems.Add(strRuleDescription)
                    'lvItem.SubItems.Add(strRuleFilter)
                    'lvItem.SubItems.Add(strRuleTest)

                    ' add it to the listview on the data page
                    lvControl.Items.Add(lvItem)

                Next ruleFound

            End If

        Catch errXml As XmlException
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(errXml, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        End Try


    End Sub



#End Region

#Region " Validation Issues "



    '
    ' load a list of Issue ids into a list control
    '
    Public Sub getRuleIssues _
        (ByRef lvControl As ListView)

        Try

            Dim qryIssues = Me.xDoc...<Issue>
            Dim intIssues As Integer = qryIssues.Count

            If lvControl IsNot Nothing Then
                lvControl.Items.Clear()
                lvControl.Columns.Clear()
                lvControl.View = View.Details
                lvControl.AllowColumnReorder = True
                lvControl.FullRowSelect = True
                lvControl.Columns.Add("Id", 50, HorizontalAlignment.Right)
            End If


            Dim lvItem As ListViewItem

            For Each issue In qryIssues

                Dim lngIssueId As Long = -1

                Dim listOfAttributes As IEnumerable(Of XAttribute) = _
                    From att In issue.Attributes() _
                    Select att
                For Each att As XAttribute In listOfAttributes
                    ' Console.WriteLine("{0}={1}", att.Name.LocalName, att.Value)
                    Select Case LCase(att.Name.LocalName)
                        Case "id"
                            lngIssueId = CLng(att.Value)

                    End Select
                Next att

                If lvControl IsNot Nothing Then
                    lvItem = New ListViewItem(lngIssueId)
                    ' add it to the listview on the data page
                    lvControl.Items.Add(lvItem)
                End If
            Next issue

        Catch errXml As XmlException
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(errXml, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        End Try

    End Sub

    '
    ' for a given issue get the ruleset/rule information
    '
    Public Sub getRuleInfo _
        (ByVal issueSource As XElement, _
         ByRef lvControl As ListView)

        Try


            Dim qryRuleInfo = issueSource...<RuleInfo>
            Dim intRuleInfo As Integer = qryRuleInfo.Count

            If lvControl IsNot Nothing Then
                lvControl.Items.Clear()
                lvControl.Columns.Clear()
                lvControl.View = View.Details
                lvControl.AllowColumnReorder = True
                lvControl.FullRowSelect = True
                lvControl.Columns.Add("index", 25, HorizontalAlignment.Right)
                lvControl.Columns.Add("rulesetID", 50, HorizontalAlignment.Right)
                lvControl.Columns.Add("rulesetNameU", 100, HorizontalAlignment.Left)
                lvControl.Columns.Add("ruleID", 50, HorizontalAlignment.Right)
                lvControl.Columns.Add("ruleNameU", 200, HorizontalAlignment.Left)
            End If

            Dim intIndex As Integer = 0
            For Each ruleinfo In qryRuleInfo
                intIndex = intIndex + 1

                Dim lngRuleSetId As Long = -1
                Dim strRuleSetNameU As String = "NoRuleSetNameU"
                Dim lngRuleId As Long = -1
                Dim strRuleNameU As String = "NoRuleNameU"

                Dim lvItem As ListViewItem


                Dim listOfAttributes As IEnumerable(Of XAttribute) = _
                    From att In ruleinfo.Attributes() _
                    Select att
                For Each att As XAttribute In listOfAttributes

                    ' Console.WriteLine("{0}={1}", att.Name.LocalName, att.Value)
                    Select Case LCase(att.Name.LocalName)
                        Case "rulesetid"
                            lngRuleSetId = CLng(att.Value)
                            ' query the ruleset
                            Dim qryRules = From rulesetSel In Me.xDoc...<RuleSet> _
                                    Where rulesetSel.@ID = CStr(lngRuleSetId)
                                    Select rulesetSel.@NameU
                            If qryRules.Count = 1 Then
                                strRuleSetNameU = qryRules.First
                            End If
                        Case "ruleid"
                            lngRuleId = CLng(att.Value)
                            ' query the ruleset
                            Dim qryRule = From ruleSel In Me.xDoc...<Rule> _
                                    Where ruleSel.@ID = CStr(lngRuleId)
                                    Select ruleSel.@NameU
                            If qryRule.Count = 1 Then
                                strRuleNameU = qryRule.First
                            End If
                    End Select
                Next att

                If lvControl IsNot Nothing Then
                    lvItem = New ListViewItem(intIndex)
                    lvItem.SubItems.Add(lngRuleSetId)
                    lvItem.SubItems.Add(strRuleSetNameU)
                    lvItem.SubItems.Add(lngRuleId)
                    lvItem.SubItems.Add(strRuleNameU)

                    ' add it to the listview on the data page
                    lvControl.Items.Add(lvItem)
                End If

            Next ruleinfo


        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        End Try

    End Sub


    '
    ' for a given issue get the target page/shape
    '
    Public Sub getIssueTargetInfo _
        (ByVal issueSource As XElement, _
         ByRef lvControl As ListView)

        Try

            Dim qryIssueTarget = issueSource...<IssueTarget>
            Dim intIssueTarget As Integer = qryIssueTarget.Count

            If lvControl IsNot Nothing Then
                lvControl.Items.Clear()
                lvControl.Columns.Clear()
                lvControl.View = View.Details
                lvControl.AllowColumnReorder = True
                lvControl.FullRowSelect = True
                lvControl.Columns.Add("index", 25, HorizontalAlignment.Left)
                lvControl.Columns.Add("pageID", 50, HorizontalAlignment.Right)
                lvControl.Columns.Add("pageNameU", 100, HorizontalAlignment.Left)
                lvControl.Columns.Add("shapeID", 75, HorizontalAlignment.Right)
                lvControl.Columns.Add("shapeNameU", 100, HorizontalAlignment.Left)
            End If


            Dim currPageShape As stcPageShape = New stcPageShape
            Dim intIndex As Integer = 0

            For Each target In qryIssueTarget
                intIndex = intIndex + 1

                Dim lngPageId As ULong = 0
                Dim strPageNameU As String = "NoPageNameU"
                Dim lngShapeId As ULong = 0
                Dim strShapeNameU As String = "NoShapeNameU"

                Dim lvItem As ListViewItem


                Dim listOfAttributes As IEnumerable(Of XAttribute) = _
                    From att In target.Attributes() _
                    Select att
                For Each att As XAttribute In listOfAttributes
                    ' Console.WriteLine("{0}={1}", att.Name.LocalName, att.Value)

                    Select Case LCase(att.Name.LocalName)
                        Case "pageid"
                            lngPageId = CULng(att.Value)
                        Case "shapeid"
                            lngShapeId = CULng(att.Value)
                    End Select
                Next att

                With currPageShape
                    .psPage = lngPageId
                    .psShape = lngShapeId
                End With

                If Me.visPackage.dictPagesID.ContainsKey(lngPageId) = True Then
                    strPageNameU = Me.visPackage.dictPagesID(lngPageId).pgNameU
                End If

                If Me.visPackage.dictPageShape.ContainsKey(currPageShape) = True Then
                    strShapeNameU = Me.visPackage.dictPageShape(currPageShape).strShpNameU.ToString
                Else
                    strShapeNameU = "ShapeNotFound"
                End If

                If lvControl IsNot Nothing Then
                    lvItem = New ListViewItem(intIndex)
                    lvItem.SubItems.Add(lngPageId)
                    lvItem.SubItems.Add(strPageNameU)
                    lvItem.SubItems.Add(lngShapeId)
                    lvItem.SubItems.Add(strShapeNameU)

                    ' add it to the listview on the data page
                    lvControl.Items.Add(lvItem)
                End If

            Next target


        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        End Try

    End Sub





#End Region




    '
    '
    '
    Public Sub New()

        Me.initValues()

        If Me.m_visPackage IsNot Nothing Then
            Me.m_visPackage = Nothing
        End If
        Me.visPackage = New clsVisPackage


    End Sub

    Public Sub initValues()

        Me._dictRules = Nothing
        Me.dictRules = New Dictionary(Of valRuleId, valRule)

    End Sub




    Protected Overrides Sub Finalize()


        If Me._dictRules IsNot Nothing Then
            Me._dictRules = Nothing
        End If

        If Me.m_visPackage IsNot Nothing Then
            Me.m_visPackage = Nothing
        End If


        MyBase.Finalize()
    End Sub
End Class

